/*
 * Indiana University Community Grid Computing Lab Software License,Version 1.1
 *
 * Copyright (c) 2002 Community Grid Computing Lab, Indiana University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *      "This product includes software developed by the Indiana University
 *       Community Grid Computing Lab (http://www.communitygrids.iu.edu/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Indiana Univeristy","Indiana Univeristy Pervasive Techonology
 *    Labs" and  "Indiana Univeristy Community Grid Computing Lab" must not be
 *    used to endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    http://www.communitygrids.iu.edu/.
 *
 * 5. Products derived from this software may not use "Indiana
 *    University" name nor may "Indiana University" appear in their name,
 *    without prior written permission of the Indiana University.
 *
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * INDIANA UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package cgl.sensorgrid.sopac.gps.filters;

import java.util.*;

import cgl.hpsearch.engine.URIBindings.*;
import cgl.narada.event.*;
import cgl.narada.matching.*;
import cgl.narada.service.*;
import cgl.narada.service.client.*;
import cgl.sensorgrid.common.*;
import cgl.sensorgrid.sopac.gps.*;
import cgl.sensorgrid.sopac.gps.threadpool.*;

/**
 * <p>Title: Sensor Grid</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: CGL</p>
 *
 * @author Galip Aydin
 * @version 1.0
 */

class StationUpDownFilter implements Runnable {

    private NBEvent nbEvent;
    private String networkName;
    private Hashtable checkHash = new Hashtable();
    private Hashtable networkHash = new Hashtable();

    StationUpDownFilter(NBEvent nbEvent_, String networkName_,
                        Hashtable networkHash_) {
        nbEvent = nbEvent_;
        networkName = networkName_;
        networkHash = networkHash_;
    }

    public void createCheckHash() {

    }

    public void run() {
        upDown(new String(nbEvent.getContentPayload()));
    }

    public void upDown(String posMsg) {

    }

}


/**
 *
 * <p>Title: Sensor Grid</p>
 *
 * <p>Description: A Grid Architecture for combining GIS services with
 * Scientific Visualization and Simulation codes</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: CGL</p>
 *
 * @author Galip Aydin
 * @version 1.0
 */
public class StationsUpDown extends Thread implements NBEventListener {
    private java.util.Properties properties = new java.util.Properties();
    private static ThreadPool pool = new ThreadPool(10);
    private String hostName;
    private String portNum;
    private String topic;
    private ClientService clientService;
    private EventConsumer consumer;
    private Profile profile;
    private String networkName;
    public static Hashtable networkHash;
    private Hashtable checkHash = new Hashtable();
    private static Hashtable minuteHash = new Hashtable();
    private static Hashtable hourHash = new Hashtable();
    private static Hashtable secHash = new Hashtable();

    private NBNativeStreamHandler nbStream;
    public StationsUpDown(String networkName_) {
        try {
            loadProperties();
            networkName = networkName_;
            GetStationsRSS g = new GetStationsRSS();
            networkHash = g.networkInfo(networkName); ;
            createCheckHash();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    private java.util.Properties loadProperties() {
        // Read properties file.
        try {
            properties = PropertyFile.loadProperties(
                    "sensorgrid.properties");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return properties;
    }


    public void getStationNames() {
        String ip = (String) networkHash.get("ip");
        String port = (String) networkHash.get("port");
        String stations = (String) networkHash.get("stations");
//        System.out.println("ip=" + ip);
//        System.out.println("port=" + port);
//        System.out.println("stations=" + stations);
        String nbTopic = "/SOPAC/GPS/Positions/" + port + "/POS";
//        System.out.println("nbTopic=" + nbTopic);
        String nbHost = properties.getProperty("nb.host");
        String nbPort = properties.getProperty("nb.port");
//        System.out.println("nbHost=" + nbHost);
//        System.out.println("nbPort=" + nbPort);
        String endpoint = "niotcp://" + nbHost + ":" + nbPort +
                          nbTopic;
//        System.out.println("endpoint=" + endpoint);
        this.hostName = nbHost;
        this.portNum = nbPort;
        this.topic = nbTopic;

        this.nbStream = new NBNativeStreamHandler(endpoint);

        try {
            clientService = SessionService.getClientService((int) (System.
                    currentTimeMillis()));
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
        initializeSubscriber();

        try {
            this.sleep(2000);
        } catch (InterruptedException ex1) {
            ex1.printStackTrace();
        }

    }


    public void stopConnection() {
        try {
            this.stopConnection();
            this.closeBrokerConnection();
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
    }

    public void initializeSubscriber() {
        Properties props = new Properties();
        /** These properties pertain to setting up a TCP link */
        props.put("hostname", this.hostName);
        props.put("portnum", this.portNum);
        try {
            initializeBrokerCommunications(props, "niotcp");
            initializeConsumer(this.topic);
        } catch (ServiceException serEx) {
            System.out.println(serEx);
        }
    }

    public void initializeBrokerCommunications(Properties props,
                                               String commType) throws
            ServiceException {
        clientService.initializeBrokerCommunications(props, commType);
    }

    public void initializeConsumer(String topic) throws ServiceException {
        profile =
                clientService.createProfile(TemplateProfileAndSynopsisTypes.
                                            STRING,
                                            topic);
        consumer = clientService.createEventConsumer(this);
        consumer.subscribeTo(profile);
    }


    int count = 0;
    String message = "";

    /**
     *
     * @param nbEvent NBEvent
     */
    public void onEvent(NBEvent nbEvent) {
        if (nbEvent.getContentPayload() != null) {
            if (nbEvent != null) {
                message += new String(nbEvent.getContentPayload());
                count++;
                if (count == 5) {
                    upDown(message);
                }
                //System.out.print(new String(nbEvent.getContentPayload()));
                //pool.assign(new StationUpDownFilter(nbEvent, networkName, networkHash));
            }
        }
    }

    public void closeBrokerConnection() throws ServiceException {
        clientService.closeBrokerConnection();
        clientService.terminateServices();
    }


    public void createCheckHash() {
        try {
            String stations = (String) networkHash.get("stations");
            System.out.println(stations);
            StringTokenizer st = new StringTokenizer(stations, ",");
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                this.checkHash.put(token, "false");
                this.secHash.put(token, "0");
                this.minuteHash.put(token, "0");
                this.hourHash.put(token, "0");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     *
     * @param posMsg String
     */
    public void upDown(String posMsg) {
        System.out.println("\nUP DOWN \n");
        StringTokenizer st = new StringTokenizer(posMsg, "\n");
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            if (!token.trim().equalsIgnoreCase("EOF")) {
                StringTokenizer st1 = new StringTokenizer(token, "\t");
                //int cnt = 0;
                while (st1.hasMoreTokens()) {
                    String token1 = st1.nextToken();
                    checkHash.remove(token1);
                    checkHash.put(token1, "true");
                    //System.out.println(token1);
                    //cnt++;
                    break;
                }
            }
//            else {
//                System.out.println("");
//            }
        }
        setSecHash(checkHash);

        Enumeration enumer = checkHash.keys();
        while (enumer.hasMoreElements()) {
            String key = (String) enumer.nextElement();
            String value = (String) checkHash.get(key);
            // System.err.println(key + " = " + value);
        }
        System.out.println("");
        count = 0;
        try {
            this.sleep(5000);
        } catch (InterruptedException ex) {
        }
    }

    int secCount = 0;
    public void setSecHash(Hashtable checkHash) {
        System.out.println("secHash");
        Enumeration enumer = checkHash.keys();

        while (enumer.hasMoreElements()) {
            String key = (String) enumer.nextElement();
            String value = (String) checkHash.get(key);
            if (value.equalsIgnoreCase("false")) {
                System.out.println(key + "=" + value);
                int falseCount = Integer.parseInt((String) secHash.get(key));
                secHash.remove(key);
                secHash.put(key,
                            (falseCount + 1) + "");
            }
        }

        Enumeration enumer1 = secHash.keys();
        while (enumer1.hasMoreElements()) {
            String key = (String) enumer1.nextElement();
            String value = (String) secHash.get(key);
            System.err.println(key + " = " + value);
        }
        System.out.println("******");

        if (secCount == 2) {
            secCount = 0;
            setMinuteHash(secHash);
        }
        secCount++;
    }

    int minCount = 0;
    public void setMinuteHash(Hashtable hash) {
        System.out.println("minuteHash");
        Enumeration enumer = hash.keys();
        while (enumer.hasMoreElements()) {
            String key = (String) enumer.nextElement();
            String value = (String) hash.get(key);
            int downcnt = Integer.parseInt(value);
            if (downcnt >= 3) {
                int falseCount = Integer.parseInt((String) minuteHash.get(key));
                minuteHash.remove(key);
                minuteHash.put(key, (falseCount + 1 + ""));
                System.out.println("***********MIN************");
                System.err.println(key + " = " + minuteHash.get(key));
            }
        }

        if (minCount == 3) {
            minCount = 0;
            setHourHash(secHash);
        }
        minCount++;
        resetHash(secHash);
    }

    int hourCount = 0;
    public void setHourHash(Hashtable hash) {
        Enumeration enumer = hash.keys();
        System.out.println("hourHash");
        while (enumer.hasMoreElements()) {
            String key = (String) enumer.nextElement();
            String value = (String) hash.get(key);
            int downcnt = Integer.parseInt(value);
            if (downcnt >= 3) {
                int falseCount = Integer.parseInt((String) hourHash.get(key));
                hourHash.remove(key);
                hourHash.put(key,
                             falseCount +
                             1 + "");
                System.out.println("*************HOUR*************");
                System.err.println(key + " = " + hourHash.get(key));
            }
        }
        hourCount++;
        if (hourCount == 24) {
            hourCount = 0;
            resetHash(hourHash);
        }
        resetHash(minuteHash);
    }

    public void resetHash(Hashtable hash) {
        Enumeration enumer = hash.keys();
        while (enumer.hasMoreElements()) {
            String key = (String) enumer.nextElement();
            hash.put(key, "0");
//            String value = (String) hash.get(key);
//            System.err.println(key + " = " + value);
        }

    }


    public static void main(String[] args) {
        try {
            StationsUpDown s = new StationsUpDown("OCRTN");
            s.getStationNames();
        } catch (Exception ex) {
        }
    }
}
